﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Zj.CourseManage.Domain.Core;
using Zj.CourseManage.DTO.Common.Pagination;
using Zj.CourseManage.DTO.Common;

namespace Zj.CourseManage.Mvc.Controllers
{
    public class DepartmentsController : Controller
    {
        private readonly DbContext _ctx;
        public DepartmentsController(DbContext ctx)
        {
            this._ctx = ctx;
        }
        // GET: Departments
        public ActionResult Index(int pageIndex = 1, int pageSize = 3, string sortField = "", string searchString = "")
        {
            var entities = _ctx.Set<Department>().AsQueryable();
            if (!string.IsNullOrEmpty(searchString))
            {
                entities = entities.Where(d => d.Name.Contains(searchString));
            }

            ViewData["pageIndex"] = pageIndex;
            ViewData["pageSize"] = pageSize;
            ViewData["sortId"] = sortField.Equals("") ? "idDesc" : "";
            ViewData["sortName"] = sortField.Equals("name") ? "nameDesc" : "name";
            ViewData["searchString"] = searchString;
            switch (sortField)
            {
                case "nameDesc":
                    entities = entities.OrderByDescending(d => d.Name);
                    break;
                default:
                    entities = entities.OrderBy(d => d.Name);
                    break;
            }
            var dtos = entities.Select(d => new DepartmentDTO() { Id = d.Id, Name = d.Name, Budget = d.Budget }).AsNoTracking();
            var list = PaginatedList<DepartmentDTO>.CreatePaging(dtos, pageIndex, pageSize);
            return View(list);
        }

        // GET: Departments/Details/5
        public ActionResult Details(int id)
        {
            return View();
        }

        // GET: Departments/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Departments/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Create(DepartmentDTO dto)
        {
            try
            {
                var entity = new Department() { Name = dto.Name };
                _ctx.Add(entity);
                await _ctx.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            catch (Exception ex)
            {
                return View();
            }
        }

        // GET: Departments/Edit/5
        public async Task<ActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            var entity = await _ctx.Set<Department>().AsNoTracking().SingleOrDefaultAsync(d => d.Id == id);
            if (entity == null)
            {
                return NotFound();
            }
            var dto = new DepartmentDTO() { Id = entity.Id, Name = entity.Name, Budget = entity.Budget };

            return View(dto);
        }

        // POST: Departments/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Edit(DepartmentDTO dto)
        {
            Department entity = null;
            try
            {
                if (ModelState.IsValid)
                {
                    entity = _ctx.Set<Department>().AsNoTracking().SingleOrDefault(d => d.Id == dto.Id);
                    if (entity == null)
                    {
                        return NotFound();
                    }
                    entity.Name = dto.Name;
                    entity.Budget = dto.Budget;
                    _ctx.Update(entity);
                    await _ctx.SaveChangesAsync();
                }
                // TODO: Add update logic here
                return RedirectToAction(nameof(Index));
            }
            catch (DbUpdateException ex)
            {
                foreach (var entry in ex.Entries)
                {
                    if (entry.Entity is Department)
                    {
                        var depart = entry.Entity as Department;
                        var clientVal = entry.Property("RowVersion").CurrentValue;
                        var original = _ctx.Set<Department>().AsNoTracking().SingleOrDefault(d=>d.Id== depart.Id).RowVersion;
                        if (original != clientVal)
                        {
                            _ctx.Update(depart);
                            await _ctx.SaveChangesAsync();
                        }

                    }
                }

                return View();
            }
        }

        public async Task<ActionResult> Delete(int? id)
        {
            try
            {
                if (id == null)
                {
                    return NotFound();
                }

                var entity = await _ctx.Set<Department>().SingleOrDefaultAsync(d => d.Id == id);
                if (entity == null)
                {
                    return NotFound();
                }
                _ctx.Remove(entity);
                await _ctx.SaveChangesAsync();
                // TODO: Add delete logic here
                return RedirectToAction(nameof(Index));
            }
            catch
            {
                return View();
            }
        }
    }
}